use rust_mcp_sdk::macros::{mcp_tool, JsonSchema};
use rust_mcp_sdk::schema::{schema_utils::CallToolError, CallToolResult, TextContent};
use serde_json::json;

use crate::tms_client::TmsClient;

#[mcp_tool(
    name = "update_vehicle_location",
    title = "Update Vehicle Location",
    description = "Update the current location of a vehicle with GPS coordinates, speed, and heading information.",
    destructive_hint = false,
    idempotent_hint = false,
    open_world_hint = false,
    read_only_hint = false
)]
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, JsonSchema)]
pub struct UpdateVehicleLocationTool {
    /// Vehicle ID
    pub vehicle_id: String,
    /// Latitude coordinate
    pub latitude: f64,
    /// Longitude coordinate
    pub longitude: f64,
    /// Speed in km/h
    pub speed: f64,
    /// Heading in degrees (0-360)
    pub heading: f64,
}

impl UpdateVehicleLocationTool {
    pub async fn run_tool(params: Self, client: &mut TmsClient) -> Result<CallToolResult, CallToolError> {
        match client.update_vehicle_location(
            params.vehicle_id,
            params.latitude,
            params.longitude,
            params.speed,
            params.heading,
        ).await {
            Ok(location_response) => {
                let response = json!({
                    "message": "Vehicle location updated successfully",
                    "success": location_response.success
                });
                Ok(CallToolResult::text_content(vec![TextContent::from(response.to_string())]))
            },
            Err(e) => Err(CallToolError::new(std::io::Error::new(std::io::ErrorKind::Other, format!("Failed to update vehicle location: {}", e)))),
        }
    }
}

#[mcp_tool(
    name = "get_vehicle_location",
    title = "Get Vehicle Location",
    description = "Get the current location and tracking information of a vehicle.",
    destructive_hint = false,
    idempotent_hint = true,
    open_world_hint = false,
    read_only_hint = true
)]
#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, JsonSchema)]
pub struct GetVehicleLocationTool {
    /// Vehicle ID
    pub vehicle_id: String,
}

impl GetVehicleLocationTool {
    pub async fn run_tool(params: Self, client: &mut TmsClient) -> Result<CallToolResult, CallToolError> {
        match client.get_vehicle_location(params.vehicle_id).await {
            Ok(location_data) => {
                Ok(CallToolResult::text_content(vec![TextContent::from(format!("{:?}", location_data))]))
            },
            Err(e) => Err(CallToolError::new(std::io::Error::new(std::io::ErrorKind::Other, format!("Failed to get vehicle location: {}", e)))),
        }
    }
}